/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
* Copyright 2018 Pelican Mapping
* http://osgearth.org
*
* osgEarth is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OSGEARTHUTIL_TMS_PACKAGER_H
#define OSGEARTHUTIL_TMS_PACKAGER_H

#include <osgEarth/Common>
#include <osgEarth/Profile>
#include <osgEarth/Map>
#include <osgEarth/TileHandler>
#include <osgEarth/TileVisitor>

namespace osgEarth { namespace Contrib
{
    class TMSPackager;

    /**
    * A TileHandler that writes out a tile from a layer in a TMS structure. packages a tile in a TMS structure
    */
    class OSGEARTH_EXPORT WriteTMSTileHandler : public TileHandler
    {
    public:
        WriteTMSTileHandler(TileLayer* layer, Map* map, TMSPackager* packager);

        TileLayer* getLayer();

        virtual bool handleTile( const TileKey& key, const TileVisitor& tv );
        virtual bool hasData( const TileKey& key ) const;
        virtual std::string getProcessString() const;

    protected:
        
        std::string getPathForTile( const TileKey &key );

    protected:
        osg::ref_ptr< TileLayer > _layer;
        osg::ref_ptr< Map > _map;
        TMSPackager* _packager;
    };

    /**
    * Utility that reads tiles from an ImageLayer or ElevationLayer and stores
    * the resulting data in a disk-based TMS (Tile Map Service) repository.
    *
    * See: http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification
    */
    class OSGEARTH_EXPORT TMSPackager
    {
    public:
        TMSPackager();      

        /**
         * Gets the destination directory
         */
        const std::string& getDestination() const;

        /**
         * Sets the destination directory
         */
        void setDestination( const std::string& destination);

        /**
         * Gets the extension to write the data with.
         */
        const std::string& getExtension() const;

        /**
         * Sets the extension to write the data with.
         */
        void setExtension( const std::string& extension);

        /**
         * Gets the elevation pixel depth, either 16 or 32.
         */
        unsigned getElevationPixelDepth() const;
        
        /**
         * Sets the elevation pixel depth, either 16 or 32.
         */
        void setElevationPixelDepth(unsigned value);
        

        /**
         * Gets whether to overwrite existing tiles or not.
         */
        bool getOverwrite() const;

        /**
         * Sets whether to overwrite existing tiles or not.
         */
        void setOverwrite(bool overwrite);

        /**
         * Gets whether to keep completely transparent images or not.
         */
        bool getKeepEmpties() const;

        /**
         * Sets whether to keep completely transparent or not.
         */
        void setKeepEmpties(bool keepEmpties);

        /**
         * Gets whether to alpha mask out portions of imagery that aren't contained in the specified bounds.
         */
        bool getApplyAlphaMask() const;

        /**
         * Sets whether to alpha mask out portions of imagery that aren't contained in the specified bounds.
         */
        void setApplyAlphaMask(bool applyAlphaMask);

        /**
         * Gets the image write options.
         */
        osgDB::Options* getOptions() const;

        /**
         * Sets the image write options.
         */
        void setWriteOptions( osgDB::Options* options );        

        /**
         * Gets the layer name to use in the TMS XML.
         */
        const std::string& getLayerName() const;

        /**
         * Sets the layer name to use in the TMS XML.
         */
        void setLayerName( const std::string& name);

        /**
         * Gets the TileVisitor used to traverse the tiles.
         */
        TileVisitor* getTileVisitor() const;

        /**
         * Sets the TileVisitor used to traverse the tiles.
         */
        void setVisitor(TileVisitor* visitor);

        /**
         * Build the tiles for the given layer and map.
         */
        void run( TileLayer* layer, Map* map );

        /**
         * Write out the TMS XML for the given layer and map.
         */
        void writeXML( TileLayer* layer, Map* map);

    protected:

        std::string _destination;
        std::string _extension;
        unsigned int _elevationPixelDepth;
        std::string _layerName;
        bool _overwrite;
        osg::ref_ptr<osgDB::Options> _writeOptions;

        unsigned int _width;
        unsigned int _height;

        bool _keepEmpties;

        bool _applyAlphaMask;

        osg::ref_ptr< TileVisitor > _visitor;
        osg::ref_ptr< WriteTMSTileHandler > _handler;

    };

} } // namespace osgEarth::Tools

#endif // OSGEARTHUTIL_TMS_PACKAGER_H
